package com.hytc.mymall.utils;

import android.util.Base64;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * Created by Administrator on 2016/12/1.
 */

public class CryptUtils {
    private static final String ALGORITHM = "DES";
    private static final String DES_CRYPT_KEY = "GDGYGDGY";
    private static byte[] iv;
    private static final char[] legalChars;
    private static ByteArrayOutputStream byteArrayOutputStream;
    static {
        legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
        CryptUtils.iv = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
    }

    private static int decode(final char c) {
        if (c >= 'A' && c <= 'Z') {
            return c - 'A';
        }
        if (c >= 'a' && c <= 'z') {
            return '\u001a' + (c - 'a');
        }
        if (c >= '0' && c <= '9') {
            return '\u001a' + ('\u001a' + (c - '0'));
        }
        switch (c) {
            default: {
                throw new RuntimeException("unexpected code: " + c);
            }
            case '+': {
                return 62;
            }
            case '/': {
                return 63;
            }
            case '=': {
                return 0;
            }
        }
    }

    private static void decode(final String s, final OutputStream outputStream) throws IOException {
        int n = 0;
        final int length = s.length();
        while (true) {
            if (n >= length || s.charAt(n) > ' ') {
                if (n == length) {
                    break;
                }
                final int n2 = (decode(s.charAt(n)) << 18) + (decode(s.charAt(n + 1)) << 12) + (decode(s.charAt(n + 2)) << 6) + decode(s.charAt(n + 3));
                outputStream.write(0xFF & n2 >> 16);
                if (s.charAt(n + 2) == '=') {
                    break;
                }
                outputStream.write(0xFF & n2 >> 8);
                if (s.charAt(n + 3) == '=') {
                    break;
                }
                outputStream.write(n2 & 0xFF);
                n += 4;
            }
            else {
                ++n;
            }
        }
    }

    public static byte[] decode(final String s) {
          byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] byteArray;
        try {
            decode(s, byteArrayOutputStream);
            byteArray = byteArrayOutputStream.toByteArray();
            final ByteArrayOutputStream byteArrayOutputStream2 = byteArrayOutputStream;
            byteArrayOutputStream2.close();
            return byteArray;
        }
        catch (IOException ex2) {
            throw new RuntimeException();
        }
    }

    public static String decryptDES(final String s) throws Exception {
        final byte[] decode = Base64.decode(URLDecoder.decode(s), 0);
        final IvParameterSpec ivParameterSpec = new IvParameterSpec(CryptUtils.iv);
        final SecretKeySpec secretKeySpec = new SecretKeySpec("GDGYGDGY".getBytes(), "DES");
        final Cipher instance = Cipher.getInstance("DES/CBC/PKCS5Padding");
        instance.init(2, secretKeySpec, ivParameterSpec);
        return new String(instance.doFinal(decode)).trim();
    }

    public static String encode(final byte[] array) {
        final int length = array.length;
        final StringBuffer sb = new StringBuffer(3 * array.length / 2);
        final int n = length - 3;
        int i = 0;
        int n2 = 0;
        while (i <= n) {
            final int n3 = (0xFF & array[i]) << 16 | (0xFF & array[i + 1]) << 8 | (0xFF & array[i + 2]);
            sb.append(CryptUtils.legalChars[0x3F & n3 >> 18]);
            sb.append(CryptUtils.legalChars[0x3F & n3 >> 12]);
            sb.append(CryptUtils.legalChars[0x3F & n3 >> 6]);
            sb.append(CryptUtils.legalChars[n3 & 0x3F]);
            i += 3;
            int n4 = n2 + 1;
            if (n2 >= 14) {
                n4 = 0;
                sb.append(" ");
            }
            n2 = n4;
        }
        if (i == -2 + (0 + length)) {
            final int n5 = (0xFF & array[i]) << 16 | (0xFF & array[i + 1]) << 8;
            sb.append(CryptUtils.legalChars[0x3F & n5 >> 18]);
            sb.append(CryptUtils.legalChars[0x3F & n5 >> 12]);
            sb.append(CryptUtils.legalChars[0x3F & n5 >> 6]);
            sb.append("=");
        }
        else if (i == -1 + (0 + length)) {
            final int n6 = (0xFF & array[i]) << 16;
            sb.append(CryptUtils.legalChars[0x3F & n6 >> 18]);
            sb.append(CryptUtils.legalChars[0x3F & n6 >> 12]);
            sb.append("==");
        }
        return sb.toString();
    }

    public static String encryptDES(final String s) throws Exception {
        final IvParameterSpec ivParameterSpec = new IvParameterSpec(CryptUtils.iv);
        final SecretKeySpec secretKeySpec = new SecretKeySpec("GDGYGDGY".getBytes(), "DES");
        final Cipher instance = Cipher.getInstance("DES/CBC/PKCS5Padding");
        instance.init(1, secretKeySpec, ivParameterSpec);
        return URLEncoder.encode(new String(Base64.encodeToString(instance.doFinal(s.getBytes()), 0)));
    }

    public static void main(final String[] array) {
        try {
            final String encryptDES = encryptDES("M123456");
            System.out.println("\u660e\u6587\uff1a" + "M123456");
            System.out.println("\u5bc6\u94a5\uff1aGDGYGDGY");
            System.out.println("\u5bc6\u6587\uff1a" + encryptDES);
            System.out.println("\u89e3\u5bc6\u540e\uff1a" + decryptDES(encryptDES));
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static String parseByte2HexStr(final byte[] array) {
        final StringBuffer sb = new StringBuffer();
        for (int i = 0; i < array.length; ++i) {
            String s = Integer.toHexString(0xFF & array[i]);
            if (s.length() == 1) {
                s = String.valueOf('0') + s;
            }
            sb.append(s.toUpperCase());
        }
        return sb.toString();
    }
}

